package vg.modules.backlight;

import java.util.Collection;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JComponent;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;

import vg.modules.backlight.components.CriticalPathSearcher;
import vg.modules.backlight.components.CycleSearcher;
import vg.modules.backlight.components.PathsSearcher;
import vg.services.data_base_manager.data.graph.Graph;
import vg.services.data_base_manager.data.graph.Vertex;
import vg.services.graph_view_manager.interfaces.graph_view.AGraphView;
import vg.services.graph_view_manager.interfaces.tab.ATab;
import vg.services.plugin_manager.event_and_request.event.AUIEvent;
import vg.services.plugin_manager.event_and_request.event.UIEventChangeTab;
import vg.services.plugin_manager.interfaces.IPlugin;
import vg.services.plugin_manager.realization.PluginParameter;
import vg.services.user_interface_manager.interfaces.AUserInterface;
import vg.services.user_interface_manager.interfaces.AUserInterfaceElement;

public class PathSelectingPlugin implements IPlugin {

	@Override
	public void install(PluginParameter parameter) throws Exception {
		new PathSelectingPanel(parameter.userInterface);
	}

	private class PathSelectingPanel extends AUserInterfaceElement {
		private AUserInterface userInterface;
		private CycleSearcher cycleSearcher;
		private PathsSearcher pathsSearcher;
		private CriticalPathSearcher criticalPathSearcher;
		private JToolBar toolBar;
		private Observer observer;
		private AGraphView view;
		
		public PathSelectingPanel(AUserInterface userinterface) {
			super("PathSelectingPlugin", null);
			this.observer = new Observer() {
				public void update(Observable o, Object arg) {
					checkView();
				}
			};

			this.pathsSearcher = new PathsSearcher();
			this.criticalPathSearcher = new CriticalPathSearcher();
			this.cycleSearcher = new CycleSearcher();
			
			toolBar = new JToolBar();
			toolBar.setFloatable(false);
			toolBar.add(cycleSearcher.getView());
			toolBar.add(pathsSearcher.getView());
			toolBar.add(criticalPathSearcher.getView());
			userinterface.addInstrument(this);
		}
		@Override
		public JComponent getView() {
			return toolBar;
		}
		@Override
		public void update(Observable o, Object arg) {
			if (arg instanceof AUIEvent) {
				AUIEvent event = (AUIEvent) arg;
				switch (event.getType()) {
					case DEF_CHANGE_UI_STYLE: {
						SwingUtilities.invokeLater(new Runnable() {
							public void run() {
								synchronized (PathSelectingPanel.this) {
									SwingUtilities.updateComponentTreeUI(PathSelectingPanel.this.toolBar);
								}
							}
						});
						break;
					}
					case DEF_CHANGE_TAB: {
						if (view != null) {
							view.getGraphObservable().removeObserver(observer);
						}
						UIEventChangeTab bufEvent = (UIEventChangeTab) event;
						ATab tab = bufEvent.getTab();
						if (tab != null) {
							switch (tab.getTabType()) {
								case ATab.DEF_GRAPH_VIEW_TAB_TYPE: {
									view = (AGraphView)tab;
									if (view != null) {
										view.getGraphObservable().addObserver(observer);
									}
									cycleSearcher.changeView(view);
									criticalPathSearcher.changeView(view);
									pathsSearcher.changeView(view);
									checkView();
									break;
								}							
							}
						}
						break;
					}
					default:break;
				}
			}
		}
		/**
		 * This method checks view on conditional (selection subgraph must contain one vertex).
		 */
		private void checkView() {
			if (!SwingUtilities.isEventDispatchThread()) {
				SwingUtilities.invokeLater(new Runnable() {
					@Override
					public void run() {
						checkView();
					}
				});
				return;
			}
			boolean cycleCheck = false;
			boolean pathCheck = false;				

			if (view != null) {
				Graph graph = view.getGraphInformation().getSelectionSubGraph();
				if (graph != null) {
					Collection<Vertex> lv = graph.getVertices();
					if (lv != null) {
						cycleCheck = (lv.size() == 1);
						pathCheck = (lv.size() == 2);
					}
				}
			}
			cycleSearcher.setEnabled(cycleCheck);
			criticalPathSearcher.setEnabled(pathCheck);
			pathsSearcher.setEnabled(pathCheck);
		}

		
	}
}
